#include "LLotnisko.h"
void * wsS(void * arg);
void * wlS(void * arg);
void * SIR(void * arg);
void * SIK(void * arg);

struct param
{
	int id;
	bool czySzeroki;
	LLotnisko * lotnisko;
};

LLotnisko::LLotnisko(Komunikacja * kom, int idLotniska)
	{

zasieg=(float)R;

	autooperator = false;	
	kom->lotnisko=this;
	
	
	for (int i=0;i<3;i++){
		awaria[i]=false;
	}
	
	for (int i=0;i<N;i++){
		listaSamolotow[i]=NULL;
	}	
		
	set_wspolczynnikObslugi(1);

komunikacja = kom;
komunikacja->DB_getLotnisko( idLotniska, this);
	cout<<"nazwa "<<nazwa<<endl;
		set_ile_szerokich_wolnych(get_ile_szerokich_pasow());
	set_ile_waskich_wolnych(get_ile_waskich_pasow());
	
};


void LLotnisko::dodajSamolot(Samolot * samolot)
{
     listaSamolotow[samolot->getID()]=samolot;
     PtEnter(0);
     samolot->setIkonka(gui->getSamolotIkonka());
  //  if (samolot->getStatus!=leci) samolot->setStatus(naZiemi);   
  
	gui->dodajdoListy_a(samolot);
	   PtLeave(0);
}


void LLotnisko::wlaczAutooperatora(){
	set_autooperator(1);
	cout<<"Aoutoperator wlaczony"<<endl;
	for (int i=0;i<N;++i)
	{
		lista_ziemia[i]=-1;
		lista_powietrze[i]=-1;
	}
	param p;
	p.lotnisko=this;
	pthread_create(&radar, NULL, SIR,(void *)&p);
	pthread_create(&kontroler,NULL,SIK,(void *)&p);
}


void LLotnisko::wylaczAutooperatora(){
	set_autooperator(0);
	pthread_join(radar,NULL);
	pthread_join(kontroler,NULL);
	cout<<"Aoutoperator wylaczony"<<endl;
}

void * wsS(void * arg)
{
	param* p=(param*)arg;
	p->lotnisko->wystartujSamolot(p->id, p->czySzeroki);
}

void * wlS(void * arg)
{
	param* p=(param*)arg;
	p->lotnisko->wyladujSamolot(p->id, p->czySzeroki);
}

void * SIR(void * arg)
{
	param* p=(param*)arg;
	p->lotnisko->SI_radar();
}

void * SIK(void * arg)
{
	param* p=(param*)arg;
	p->lotnisko->SI_kontroler();
}

void LLotnisko::SI_radar()
{
	while(autooperator)
	{
		for(int ir=0;ir<N;++ir)
		{
		 	if(listaSamolotow[ir]==NULL)
			{
				lista_ziemia[ir]=-1;
				lista_powietrze[ir]=-1;
			}
			else if((listaSamolotow[ir]->getStatus()==chceLadowac || listaSamolotow[ir]->getStatus()==koluje) && lista_powietrze[ir]==-1)
			{
				lista_powietrze[ir]=time(NULL);
			}
			else if(listaSamolotow[ir]->getStatus()==chceStartowac && lista_ziemia[ir]==-1)
			{
				lista_ziemia[ir]=time(NULL);
			}
			else if(listaSamolotow[ir]->getStatus()!=chceStartowac && lista_ziemia[ir]!=-1)
			{
				lista_ziemia[ir]=-1;
			}
			else if((listaSamolotow[ir]->getStatus()!=chceLadowac || listaSamolotow[ir]->getStatus()!=koluje)&& lista_powietrze[ir]!=-1)
			{
				lista_powietrze[ir]=-1;
			}
		}
		delay(50);
	}
}

void LLotnisko::SI_kontroler()
{
	while(autooperator)
	{
		long double best_time=-1;
		int chosen=-1;
		for(int ik=0;ik<N;++ik)
		{
			if(lista_powietrze[ik]!=-1 && time(NULL)-lista_powietrze[ik]>best_time)
			{
				if(listaSamolotow[ik]->awaria || (chosen==-1 && !listaSamolotow[ik]->awaria) ||(chosen!=-1 &&(!listaSamolotow[ik]->awaria && !listaSamolotow[chosen]->awaria)))
				{
					best_time=time(NULL)-lista_powietrze[ik];
					chosen=ik;
				}
			}
			if(lista_ziemia[ik]!=-1 && time(NULL)-lista_ziemia[ik]>best_time)
			{
				if(listaSamolotow[ik]->awaria || (chosen==-1 && !listaSamolotow[ik]->awaria) || (chosen!=-1 && (!listaSamolotow[ik]->awaria && !listaSamolotow[chosen]->awaria)))
				{
					best_time=time(NULL)-lista_ziemia[ik];
					chosen=ik;
				}		
			}
		}
		if(chosen!=-1)
		{
			param p;
			p.id=chosen;
			p.lotnisko=this;
			if(ile_szerokich_wolnych >0 && listaSamolotow[chosen]->getPas())
			{
				pthread_t watek;
				p.czySzeroki=true;
				if(lista_powietrze[chosen]!=-1)
				{
					pthread_create(&watek,NULL,wlS, (void *)&p);
				}
				else
				{
					pthread_create(&watek,NULL,wsS,(void*)&p);
				}
			}
			else if(!listaSamolotow[chosen]->getPas() && (ile_szerokich_wolnych>0 || ile_waskich_wolnych>0))
			{
				pthread_t watek;
				p.czySzeroki=false;
				if(lista_powietrze[chosen]!=-1)
				{
					pthread_create(&watek, NULL, wlS, (void *)&p);
				}
				else
				{
					pthread_create(&watek, NULL, wsS, (void *)&p);
				}
			}
			else //zakaz
			{
				if(lista_powietrze[chosen]!=-1)
				{
					zakazWyladowania(chosen,1);				
				}
				else
				{
					zakazStartu(chosen,1);
				}
			}
			for(int ik2=0;ik2<N;++ik2)
			{
				if(ik2!=chosen)
				{
					if(lista_ziemia[ik2]!=-1)
					{
						zakazStartu(ik2,1);
					}
					if(lista_powietrze[ik2]!=-1)
					{
						zakazWyladowania(ik2,1);
					}
				}
			}
		}
		delay(100);
	}
}

void LLotnisko::getLotnisko(int id_lotniska_, string nazwa_, int pojemnosc_, float szerokosc_, float dlugosc_, 
							int ile_waskich_pasow_, int ile_szerokich_pasow_)				
							{
							id_lotniska=id_lotniska_;
							nazwa=nazwa_;
							pojemnosc=pojemnosc_;
							szerokosc=szerokosc_;
							dlugosc=dlugosc_;
							ile_waskich_pasow=ile_waskich_pasow_;
							ile_szerokich_pasow=ile_szerokich_pasow_;
}
	


//wywoluje komunikacja
//podtyp 0 - zla pogoda
//podtyp 1 - lotnisko uszkodzone
//wersja wstepna
void LLotnisko::setAwaria (string nazwa, string podtyp,int  stopien){

	cout << "JEST AWARIA DO USTAWIENIA "<< nazwa <<"    "<<podtyp<<"    "<<stopien<<endl;


	string p = "1";	
	string w = "2";
	bool juzjest = false;

	for(int i = 0; i < nazwya.size(); i++){
		if(nazwya[i] == nazwa)
			if(podtypya[i] == podtyp){ 
					juzjest = true;
			}
	}  

	if(juzjest == false){
		nazwya.push_back(nazwa);
		podtypya.push_back(podtyp);
		stopniea.push_back(stopien);
	}
	cout << "CZY TAKA AWARIA JUZ JEST???? "<<juzjest<<endl;	

	cout << "W TABLICY"<<endl;
	for(int i = 0; i < nazwya.size(); i++){
		cout << nazwya[i] <<"    "<<podtypya[i]<<"    "<<stopniea[i]<<endl;
	}
	cout<<"------------------"<<endl;	


	if(juzjest == false && podtyp == w){	
		if(stopien  < 5){

			if(get_wspolczynnikObslugi() < 2)
				set_wspolczynnikObslugi(2);
			
			cout<<"Wspolczynnik obslugi "<<get_wspolczynnikObslugi()<<endl;
		}
		else if(stopien >= 5 && stopien < 9){  
			if(get_wspolczynnikObslugi() < 4)			
				set_wspolczynnikObslugi(4);		
			cout<<"Wspolczynnik obslugi "<<get_wspolczynnikObslugi()<<endl;
		}
		else if(stopien >= 9){  
			if(get_wspolczynnikObslugi() < 6)			
				set_wspolczynnikObslugi(6);		
			cout<<"Wspolczynnik obslugi "<<get_wspolczynnikObslugi()<<endl;
		}
	}
	
	if(juzjest == false && podtyp == p){
		if(stopien < 5){
			if(get_ile_szerokich_wolnych() > 0)  
				set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() - 1);
			if(get_ile_waskich_wolnych() > 0)
				set_ile_waskich_wolnych(get_ile_waskich_wolnych() - 1);
			gui->rysujPaski();
			
		}
		else if(stopien >= 5 && stopien <9){  
			if(get_ile_szerokich_wolnych() > 2)  
				set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() - 3);
			else
				set_ile_szerokich_wolnych(0);
			
			if(get_ile_waskich_wolnych() > 2)
				set_ile_waskich_wolnych(get_ile_waskich_wolnych() - 3);
			else
				set_ile_waskich_wolnych(0);
	
			gui->rysujPaski();
	
		
		}
		else if(stopien >= 9){ 
	
			set_ile_szerokich_wolnych(0);
			set_ile_waskich_wolnych(0);
			gui->rysujPaski();
	
		}
	}
}


void LLotnisko::usunAwarie (){
	set_wspolczynnikObslugi(1);		
	set_ile_szerokich_wolnych(get_ile_szerokich_pasow());
	set_ile_waskich_wolnych(get_ile_waskich_pasow());
	gui->rysujPaski();

}




//ma DOPISYWAC stringi awarii pod okreslony podtyp 0 dla pasow A, 1 dla pasow B oraz 2 dla czasu hangarowania.
//i ma inta o stopniu awarii
void LLotnisko::resetAwaria (string nazwa){	

	cout <<endl<< "reset awaria " << nazwa <<endl;


	string p = "1";
	string w = "2";

	string pdt;
	int stp;

	for(int i = 0; i < nazwya.size(); i++){
		if(nazwya[i]==nazwa){
			cout << "usuwam awarie"<<nazwa<<endl;
			pdt = podtypya[i];						
			stp = stopniea[i];
			nazwya.erase(nazwya.begin()+i);
			podtypya.erase(podtypya.begin()+i);
			stopniea.erase(stopniea.begin()+i);
			
	
		}
	}	


	int maxp = 0;
	int maxw = 0;

	cout << "Przeglad tablicy:"<<endl;
	for(int i = 0; i < nazwya.size(); i++){
		cout << nazwya[i] <<"    "<<podtypya[i]<<"    "<<stopniea[i]<<endl;
		if(podtypya[i] == p){
			if(stopniea[i] > maxp){
				maxp = stopniea[i];

			}
		}
		if(podtypya[i] == w){
			if(stopniea[i] > maxw){
				maxw = stopniea[i];

			}
		}



	}
	
	cout<<"koniec tablicy"<<endl;
	cout <<"MAXP "<<maxp<<" MAXW "<<maxw<<endl;		


	if(pdt == w){	
		if(maxw  == 0){
			set_wspolczynnikObslugi(1);
			cout<<"Wspolczynnik obslugi 1"<<endl;
		}
		if(maxw  < 5 && maxw  > 0){
			set_wspolczynnikObslugi(2);
			cout<<"Wspolczynnik obslugi 2"<<endl;
		}
		else if(maxw >= 5 && maxw < 9){  
			set_wspolczynnikObslugi(4);		
			cout<<"Wspolczynnik obslugi 4"<<endl;
		}
		else if(maxw >= 9){  
			set_wspolczynnikObslugi(6);		
			cout<<"Wspolczynnik obslugi 6"<<endl;
		}
	}

	


	if(pdt ==p){
		if(stp < 5 && maxp <9){

			if(get_ile_szerokich_wolnych() < get_ile_szerokich_pasow())  
				set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() + 1);
			if(get_ile_waskich_wolnych() < get_ile_waskich_pasow())
				set_ile_waskich_wolnych(get_ile_waskich_wolnych() + 1);
			gui->rysujPaski();
			
		}
		else if(stp >= 5 && stp <9 && maxp< 9){  
			if(get_ile_szerokich_wolnych() < get_ile_szerokich_pasow() -2 )  
				set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() + 3);
			else
				set_ile_szerokich_wolnych(get_ile_szerokich_pasow());
			
			if(get_ile_waskich_wolnych() < get_ile_waskich_pasow() - 2)
				set_ile_waskich_wolnych(get_ile_waskich_wolnych() + 3);
			else
				set_ile_waskich_wolnych(get_ile_waskich_pasow());
	
			gui->rysujPaski();
	
		}		
		else if(stp >= 9){ 
	
			set_ile_szerokich_wolnych(get_ile_szerokich_pasow());
			set_ile_waskich_wolnych(get_ile_waskich_pasow());
			
				if(maxp < 5 && maxp > 0){
					if(get_ile_szerokich_wolnych() > 0)  
						set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() - 1);
					if(get_ile_waskich_wolnych() > 0)
						set_ile_waskich_wolnych(get_ile_waskich_wolnych() - 1);
					gui->rysujPaski();
					
				}
				else if(maxp >= 5 && maxp <9){  
					if(get_ile_szerokich_wolnych() > 2)  
						set_ile_szerokich_wolnych(get_ile_szerokich_wolnych() - 3);
					else
						set_ile_szerokich_wolnych(0);
					
					if(get_ile_waskich_wolnych() > 2)
						set_ile_waskich_wolnych(get_ile_waskich_wolnych() - 3);
					else
						set_ile_waskich_wolnych(0);
			
					gui->rysujPaski();
			
				
				}
				else if(maxp >= 9){ 
			
					set_ile_szerokich_wolnych(0);
					set_ile_waskich_wolnych(0);
					gui->rysujPaski();
			
				}

			gui->rysujPaski();
	
		}




	}


}






//Oprocz id argumentem funkcji jest rowniez czySzeroki poniewaz male samoloty
//moga startowac zarowno z waskich jak i szerokich pasow nie mozna zatem wnioskowac
//o tym ktory licznik zwiekszac na podstawie samolot.getPas() 
void LLotnisko::wystartujSamolot(int id, bool czySzeroki){

	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
		|| listaSamolotow[id]->getStatus() != chceStartowac){
		return ;
	}


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//---------------------------------------------- pasy --      -------------------------------------------------
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	if(czySzeroki == false){
		cout << " Zmniejszam liczbe wolnych waskich pasow" <<endl;
		
		if(ile_waskich_pasow > 0){	
			ile_waskich_wolnych --;	
			cout <<"Ogolnie "<< ile_waskich_pasow <<" Wolnych "<<ile_waskich_wolnych<<endl;
		}
		else{
			cout << "Brak wolnych waskich pasow"<<endl;
			return;
		}
		
	}
	else{
		if(ile_szerokich_pasow > 0){	
			ile_szerokich_wolnych --;	
			cout <<"Ogolnie "<< ile_szerokich_pasow <<" Wolnych "<<ile_szerokich_wolnych<<endl;
		}
		else{
			cout << "Brak wolnych szerokich pasow"<<endl;
			return;			
		}
	}
	gui->rysujPaski();
	listaSamolotow[id]->setStatus(startuje);
	sleep((int)(wspolczynnikObslugi* listaSamolotow[id]->getCzas()));

	komunikacja->Kom_wystartujSamolot(id);

	

	listaSamolotow[id]->setStatus(leci);


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------- pasy ++      -------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	if(czySzeroki == false){
		cout << " Zwiekszam liczbe wolnych waskich pasow" <<endl;
		
		ile_waskich_wolnych ++;	
		cout <<"Ogolnie "<< ile_waskich_pasow <<" Wolnych "<<ile_waskich_wolnych<<endl;
	}
	else{
		cout << " Zwiekszam liczbe wolnych szerokich pasow" <<endl;

		ile_szerokich_wolnych ++;	
		cout <<"Ogolnie "<< ile_szerokich_pasow <<" Wolnych "<<ile_szerokich_wolnych<<endl;
	}
	gui->rysujPaski();

} 




void LLotnisko::zakazStartu(int id, int czas){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=chceStartowac){
		return ;
	}
	komunikacja->Kom_zakazStartu(id, czas);
}



void LLotnisko::wyladujSamolot(int id, bool czySzeroki){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=chceLadowac){
		return ;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------- pasy --      -------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	if(czySzeroki == false){
		cout << " Zmniejszam liczbe wolnych waskich pasow" <<endl;
		
		if(ile_waskich_pasow > 0){	
			ile_waskich_wolnych --;	
			cout <<"Ogolnie "<< ile_waskich_pasow <<" Wolnych "<<ile_waskich_wolnych<<endl;
		}
		else{
			cout << "Brak wolnych waskich pasow"<<endl;
			return;
		}
		
	}
	else{
		if(ile_szerokich_pasow > 0){	
			ile_szerokich_wolnych --;	
			cout <<"Ogolnie "<< ile_szerokich_pasow <<" Wolnych "<<ile_szerokich_wolnych<<endl;
		}
		else{
			cout << "Brak wolnych szerokich pasow"<<endl;
			return;			
		}
	}
	gui->rysujPaski();


	cout<<" WYLADUJ SAMOLOT"<<endl;
	listaSamolotow[id]->setStatus(laduje);
	komunikacja->Kom_wyladujSamolot(id);


	sleep((int)(wspolczynnikObslugi* listaSamolotow[id]->getCzas()));
	
	listaSamolotow[id]->setStatus(naZiemi);
	cout << "Zmiana statusu z leci na naZiemi"<<endl;


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------- pasy ++      -------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	if(czySzeroki == false){
		cout << " Zwiekszam liczbe wolnych waskich pasow" <<endl;
		
		ile_waskich_wolnych ++;	
		cout <<"Ogolnie "<< ile_waskich_pasow <<" Wolnych "<<ile_waskich_wolnych<<endl;
	}
	else{
		cout << " Zwiekszam liczbe wolnych szerokich pasow" <<endl;

		ile_szerokich_wolnych ++;	
		cout <<"Ogolnie "<< ile_szerokich_pasow <<" Wolnych "<<ile_szerokich_wolnych<<endl;
	}
	gui->rysujPaski();

	hangarujSamolot(id);

}



void LLotnisko::zakazWyladowania(int id, int czas){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=chceLadowac){
		return ;
	}

	listaSamolotow[id]->setStatus(koluje);
	komunikacja->Kom_zakazLadowania(id,czas);
	cout << "Zmiana statusu z leci na koluje"<<endl;

}




//dostaje id float i float i bool awaria
void LLotnisko::polozenieSamolotu(int id, float polozenieX,float polozenieY){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL){
		return ;
	}

	listaSamolotow[id]->ustalPolozenie(gui,polozenieX, polozenieY);


}



void LLotnisko::odeslijSamolot(int id){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=chceLadowac){
		return ;
	}

	cout << "Lec gdzie indziej"<<endl;

	listaSamolotow[id]->setStatus(leci);
	komunikacja->Kom_odeslijSamolot(id);
}



void LLotnisko::hangarujSamolot(int id){

	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=naZiemi){
		return ;
	}
	
	listaSamolotow[id]->setStatus(hangar);
	cout << "Zmiana statusu z naZiemi na hangar"<<endl;
	
	PtEnter(0);
	gui->zniknijzListy(id);
	PtDestroyWidget( listaSamolotow[id]->getIkonka());
	PtLeave(0);
	delete listaSamolotow[id];
	sleep((int)(wspolczynnikObslugi* listaSamolotow[id]->getCzas()));  //Kamil: Pozwoliem sobie tutaj zmienic koeljnosc najpierw sleepuj wzgledem  listaSamolotow[id]->getCzas() a pozniej nuluj pozycje w tablicy, wczesnij wyskakiwal oczywisty segmental
	listaSamolotow[id]=NULL;
	komunikacja->Kom_samolotKILL( id);
}



void LLotnisko::gotowyDoStartu(int id){
	if (id >= N || id < 0 || listaSamolotow[id]==NULL 
					|| listaSamolotow[id]->getStatus()!=hangar){
		return ;
	}

	listaSamolotow[id]->setStatus(chceStartowac);
	cout << "Zmiana statusu z hangar na chceSartowac"<<chceStartowac<<endl;

}



//GETYSETY

int LLotnisko::get_id_lotniska(){return id_lotniska;}
string LLotnisko::get_nazwa(){return nazwa;}
int LLotnisko::get_pojemnosc(){return pojemnosc;}
int LLotnisko::get_ile_samolotow(){return ile_samolotow;}
float LLotnisko::get_szerokosc(){return szerokosc;}
float LLotnisko::get_dlugosc(){return dlugosc;}
int LLotnisko::get_ile_szerokich_pasow(){return ile_szerokich_pasow;}
int LLotnisko::get_ile_waskich_pasow(){return ile_waskich_pasow;}
int LLotnisko::get_ile_szerokich_wolnych(){return ile_szerokich_wolnych;}
int LLotnisko::get_ile_waskich_wolnych(){return LLotnisko::ile_waskich_wolnych;}
float LLotnisko::get_wspolczynnikObslugi(){return wspolczynnikObslugi;}
bool LLotnisko::get_autooperator(){return autooperator;}

void LLotnisko::set_id_lotniska(int id){id_lotniska = id;}
void LLotnisko::set_nazwa(string n){nazwa =n;}
void LLotnisko::set_pojemnosc(int p){pojemnosc=p;}
void LLotnisko::set_ile_samolotow(int i){ile_samolotow=i;}
void LLotnisko::set_szerokosc(int s){szerokosc=s;}
void LLotnisko::set_dlugosc(int d){dlugosc=d;}
void LLotnisko::set_ile_szerokich_pasow(int i){ile_szerokich_pasow=i;}
void LLotnisko::set_ile_waskich_pasow(int i){ile_waskich_pasow=i;}
void LLotnisko::set_ile_szerokich_wolnych(int i){ile_szerokich_wolnych=i;}
void LLotnisko::set_ile_waskich_wolnych(int i){ile_waskich_wolnych=i;}
void LLotnisko::set_wspolczynnikObslugi(float w){wspolczynnikObslugi = w;}
void LLotnisko::set_autooperator(bool b){autooperator = b;}





